package com.jochen.core.screen;

import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Screen
import com.badlogic.gdx.utils.viewport.ScalingViewport
import com.badlogic.gdx.scenes.scene2d.Stage
import com.jochen.core.world.*
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.InputProcessor
import kotlin.reflect.KClass
import com.badlogic.gdx.utils.Scaling
import kotlin.math.roundToInt
import com.badlogic.gdx.graphics.GL20

abstract class BaseScreen(
    protected val game: GdxGame,
    protected val screenManager: ScreenManager,
    private val targetHeight: Int = 680,
    scaling: Scaling = Scaling.fill
    ): Screen{
    
    var isGlClear: Boolean = true
    
    var screenWidth: Int = 0
    var screenHeight: Int = 0
    init{
        screenHeight = targetHeight
        updateScreenSize(Gdx.graphics.width,Gdx.graphics.height)
    }
    protected val stage: Stage = Stage(ScalingViewport(scaling,screenWidth.toFloat(),screenHeight.toFloat()),game.batch)
    
    private var isPaused: Boolean = false
    
    final override fun show(){
        addProcessor(stage)
        enter()
    }
    
    final override fun hide(){
        removeProcessor(stage)
        exit()
    }
    
    final override fun resume(){
        resumeChange()
        isPaused = false
    }
    
    final override fun render(delta: Float) {
        if(isGlClear){
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)
            val color = game.glClearColor
            Gdx.gl.glClearColor(color.r,color.g,color.b,color.a)
        }
        
        if (!isPaused) update(delta)
        
        stage.run {
            act(delta)
            draw()
        }
    }
    
    private fun updateScreenSize(width: Int, height: Int) {
        screenWidth = (targetHeight * width.toFloat() / height).roundToInt()
        Gdx.app.log(this::class.simpleName, "计算后的屏幕尺寸: ${screenWidth}x$screenHeight") 
    }
    
    final override fun pause(){
        pauseChange()
        isPaused = true
    }
    
    final override fun resize(width: Int,height: Int){
        updateScreenSize(width,height)
        stage.viewport.update(screenWidth,screenHeight,true)
        viewSizeChange()
    }
    
    //子类监听屏幕变化函数,占停前，恢复前
    open fun viewSizeChange(){}
    open fun pauseChange(){}
    open fun resumeChange(){}
    open fun enter(){}
    open fun exit(){}
    abstract fun update(delta: Float)
    
    override fun dispose(){
        stage.dispose()
    }
    
    fun destroyScreen(type: KClass<out BaseScreen>) = screenManager.destroyScreen(type)
    fun addScreen(screen: BaseScreen) = screenManager.addScreen(screen)
    fun setScreen(type: KClass<out BaseScreen>) = screenManager.setScreen(type)
    fun setScreen(type: KClass<out BaseScreen>,trsType: KClass<out Transition>) = screenManager.setScreen(type,trsType)
    fun getTransitions(type: KClass<out Transition>) = screenManager.getTransitions(type)
    fun addActor(actor: Actor) = stage.addActor(actor)
    fun addProcessor(ps: InputProcessor) = screenManager.addProcessor(ps)
    fun removeProcessor(ps: InputProcessor) = screenManager.removeProcessor(ps)
    
    
}